﻿/*
 *	Created/modified in 2011 by Simon Baer
 *	
 *  Based on the Code Project article by Nicolas Wälti:
 *  http://www.codeproject.com/KB/cpp/PopupNotifier.aspx
 * 
 *  Licensed under the Code Project Open License (CPOL).
 */

using LightCAD.Runtime;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace LightCAD.UI
{
    /// <summary>
    /// Non-visual component to show a notification window in the right lower
    /// corner of the screen.
    /// </summary>
    [ToolboxBitmap(typeof(PopupInfo), "Icon.ico")]
    [DefaultEvent("Click")]
    public class HistoryCmdInfo : UserControl, IHistoryCmdObject
    {

        public static HistoryCmdInfo Instance { get; } = new HistoryCmdInfo();

        public bool IsShow { get; set; } = false;

        #region Windows API
        private const int SW_SHOWNOACTIVATE = 4;
        private const int HWND_TOPMOST = -1;
        private const uint SWP_NOACTIVATE = 0x0010;

        [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
        static extern bool SetWindowPos(
         int hWnd,             // Window handle
         int hWndInsertAfter,  // Placement-order handle
         int X,                // Horizontal position
         int Y,                // Vertical position
         int cx,               // Width
         int cy,               // Height
         uint uFlags);         // Window positioning flags

        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        private void InitializeComponent()
        {
            SuspendLayout();
            // 
            // HistoryCmdInfo
            // 
            BackColor = SystemColors.Control;
            Name = "HistoryCmdInfo";
            Size = new Size(136, 130);
            ResumeLayout(false);
        }

        static void ShowInactiveTopmost(Form frm)
        {
            ShowWindow(frm.Handle, SW_SHOWNOACTIVATE);
            SetWindowPos(frm.Handle.ToInt32(), HWND_TOPMOST,
            frm.Left, frm.Top, frm.Width, frm.Height,
            SWP_NOACTIVATE);
        }
        #endregion

        public HistoryCmdInfoForm frmPopup;

        public IHistoryCmdControl Control
        {
            get { return frmPopup; }
        }

        /// <summary>
        /// Create a new instance of the popup component.
        /// </summary>
        public HistoryCmdInfo()
        {
            // set default values


            frmPopup = new HistoryCmdInfoForm(this);
            frmPopup.FormBorderStyle = FormBorderStyle.None;
            frmPopup.StartPosition = FormStartPosition.Manual;
            frmPopup.FormBorderStyle = FormBorderStyle.None;
        }

        /// <summary>
        /// Show the notification window if it is not already visible.
        /// If the window is currently disappearing, it is shown again.
        /// </summary>
        public void Show(int scrLeft, int scrTop)
        {
            if (!frmPopup.Visible)
            {
                frmPopup.Location = new Point(scrLeft, scrTop);
                //frmPopup.Visible = true;//这句会导致抢焦点
                ShowInactiveTopmost(frmPopup);
            }
            else
            {
                frmPopup.Invalidate();
            }
            this.IsShow = true;
        }

        /// <summary>
        /// Hide the notification window.
        /// </summary>
        public void Hide()
        {
            frmPopup.Visible = false;
            this.IsShow = false;
        }

        public void SetPosition(int scrLeft, int scrTop)
        {
            frmPopup.Location = frmPopup.PointToScreen(new Point(scrLeft, scrTop));
        }

        public void InvokeMethod(string methodName, params object[] args)
        {
            throw new NotImplementedException();
        }
        public void SetValidCommonds(List<string> cmds)
        {
            this.frmPopup.lbCmds.Items.Clear();
            if (cmds == null || cmds.Count == 0)
                return;

            for (int i = cmds.Count - 1; i >= 0; i--)
            {
                this.frmPopup.lbCmds.Items.Add(cmds[i]);
            }

            this.frmPopup.lbCmds.SelectedIndex = 0;
        }

        public string GetCurrentCmd()
        {
            return (string)this.frmPopup.lbCmds.SelectedItem;
        }

        public void Up()
        {
            this.frmPopup.lbCmds.SelectedIndex = Math.Max(0, this.frmPopup.lbCmds.SelectedIndex - 1);
        }

        public void Down()
        {
            frmPopup.lbCmds.SelectedIndex = Math.Min(frmPopup.lbCmds.Items.Count - 1, frmPopup.lbCmds.SelectedIndex + 1);
        }

        public void AttachExecuteAction(Action<string> action)
        {
            this.frmPopup.AttachExecuteAction(action);
        }
    }
}
